Array.prototype.includes2 = function (item) {
    for (var i = 0; i < this.length; i++) {
        // if (this[i] === item || (this[i] !== this[i] && item !== item)) {
        if (this[i] === item || (isNaN(this[i]) && isNaN(item))) {
            return true;
        }
    }
    return false;
};

// var arr = [1,2 ,3 , NaN];
// console.log(arr.includes2(1))
// console.log(arr.includes2(NaN))
// console.log(arr.indexOf(NaN))

Array.prototype.join2 = function (sep = ',') {
    var str = '';
    for (var i = 0; i < this.length; i++) {
        str += this[i] + (i === this.length - 1 ? '' : sep);
    }
    return str;
};

// var arr = [1, 2, 3];
// console.log(arr.join2())
// console.log(arr.join2(''))

Array.prototype.reduce2 = function (callbackfn, preItem) {
    var i = 0;
    if (preItem === undefined) { //如果没有预传值，则代表默认为第一个元素，从第2个元素开始遍历
        preItem = this[0];
        i++;
    }
    for (var len = this.length; i < len; i++) {
        preItem = callbackfn(preItem, this[i], i, this);
    }
    return preItem;
};

// var arr = [1, 2, 3, 4];
// var callbackfn = function (pre, cur, index, arr) {
//     console.log(pre, cur, index);
//     return pre + cur;
// };
// var res = arr.reduce(callbackfn, 5);
// console.log(res);

// console.log('------------');
// var res2 = arr.reduce2(callbackfn, 5);
// console.log(res2);

// var res3 = arr.filter(item => item > 2).map(i => i * 2);
// console.log(res3);
// var res4 = arr.reduce2(function (pre, cur) {
//     if (cur > 2) {
//         pre.push(cur * 2);
//     }
//     return pre;
// }, []);
// console.log(res4);


Array.prototype.concat2 = function (arr) {
    var res = [];
    for (var i = 0; i < this.length; i++) {
        res.push(this[i]);
    }
    if (Array.isArray(arr)) {
        for (i = 0; i < arr.length; i++) {
            res.push(arr[i]);
        }
    } else {
        res.push(arr);
    }
    return res;
};

// console.log([1, 2, 3].concat([4,5]));
// console.log([1, 2, 3].concat(4));
// console.log([1, 2, 3].concat2([4,5]));
// console.log([1, 2, 3].concat2(4));


Array.prototype.find2 = function (callback, scope) {
    for (let i = 0; i < this.length; i++) {
        const element = this[i];
        if (callback.call(scope, element, i, this)) {
            return element;
        }
    }
};

// var arr = ['a', 'b', 'c'];
// console.log(arr.find(i => i === 'bff'));
// console.log(arr.find2(i => i === 'bff'));

Array.prototype.findIndex2 = function (callback, scope) {
    for (let i = 0; i < this.length; i++) {
        const element = this[i];
        if (callback.call(scope, element, i, this)) {
            return i;
        }
    }
    return -1;
};


Array.prototype.some2 = function (callback, scope) {
    for (let i = 0; i < this.length; i++) {
        const element = this[i];
        if (callback.call(scope, element, i, this)) {
            return true;
        }
    }
    return false;
};

Array.prototype.every2 = function (callback, scope) {
    for (let i = 0; i < this.length; i++) {
        const element = this[i];
        if (!callback.call(scope, element, i, this)) {
            return false;
        }
    }
    return true;
};

Array.prototype.forEach2 = function (callback, scope) {
    for (let i = 0; i < this.length; i++) {
        const element = this[i];
        callback.call(scope, element, i, this);
    }
};

Array.prototype.map2 = function (callback, scope) {
    var arr = [];
    for (let i = 0; i < this.length; i++) {
        const element = this[i];
        arr.push(callback.call(scope, element, i, this));
    }
    return arr;
};

Array.from2 = function (arr) {

}

Array.isArray2 = function (arr) {
    return Object.prototype.toString.call(arr) === '[object Array]';
};

// console.log(Array.isArray({'a':'b'}));
// console.log(Array.isArray2({'a':'b'}));

Array.prototype.flat2 = function (depth = 1) {
    var arr = [];
    for (var i = 0; i < this.length; i++) {
        if (Array.isArray(this[i]) && depth > 0) {
            arr.push(...this[i].flat2(depth-1));
        } else {
            arr.push(this[i]);
        }
    }
    return arr;
};

// var arr = [0, 1, 2, [[[3, 4]]]];
var arr = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
console.log(arr.flat(3))
console.log(arr.flat2(3))

console.log(arr.flat(Infinity))
console.log(arr.flat2(Infinity))

var testArr2 = [0, [1, [2, [3, [4, [5]]]]]];
console.log(testArr2.flat())